import { NetPlayer, NetRoom } from "./NetInfos";
import $, { ajax } from "jquery";
import HomeUi from "./HomeUi";
import { NetInfoBase } from "./NetInfos";
import { HallOrderType } from "./Model";
import "../css/homestyle.css";
import Tools from "./Tools";
import Enumerable from "linq";

const host = window.document.location.host;
const hostIp = host.split(":")[0];
var myPlayer: NetPlayer;
var ws: WebSocket = null;
var rktimer: NodeJS.Timeout;
var rmtimer: NodeJS.Timeout;
var rankCycle = 5000; //排名更新周期
var roomsCycle = 3000; //房间信息更新周期
var rooms: NetRoom[]; //当前房间列表
let onloking = false; //标识是否正在匹配

var conTimeOut: NodeJS.Timeout;
var sendBarInterval: NodeJS.Timeout;

HomeUi.init();
connectServer();
eventbind();

function connectServer() {
  HomeUi.showLoad("正在连接");
  ws = new WebSocket("ws://" + hostIp + ":8081/HallChat");
  ws.onopen = playerConnect;
  ws.onmessage = onData;
  ws.onclose = onClose;
  conTimeOut = setTimeout(connectTimeOut, 5000);
  sendBarInterval = setInterval(sendSysBar, 30000);
}

function connectTimeOut() {
  HomeUi.hideLoad();
  showConnectFail();
}

/**显示连接超时弹出层 */
function showConnectFail() {
  Tools.showMsbox("服务器连接已断开！点击确认重新连接", "连接断开", Tools.MsButtons.okAndCancel, (yes: boolean) => {
    if (yes) {
      Tools.skipHall();
    } else {
      console.log("关闭页面");
      window.location.href = `http://www.baidu.com`;
    }
  });
}

function eventbind() {
  HomeUi.addEventLinstener(HomeUi.event_开始匹配, () => {
    if (!isConnect()) {
      Tools.showPrompt("未连接到服务器!", 2000, Tools.PromptIcon.erro);
      return;
    }
    HomeUi.showMatching();
    sendData("", HallOrderType.进入匹配队列);
  });
  HomeUi.addEventLinstener(HomeUi.event_取消匹配, () => {
    HomeUi.hideMatching();
    sendData("", HallOrderType.退出匹配队列);
  });
  HomeUi.addEventLinstener(HomeUi.event_信息保存, (e) => {
    let json = JSON.stringify(e);
    sendData(json, HallOrderType.更新玩家信息);
  });
  HomeUi.addEventLinstener(HomeUi.event_创建房间, (params) => {
    let json = JSON.stringify(params);
    sendData(json, HallOrderType.创建房间);
    HomeUi.showLoad("正在创建...");
  });
  HomeUi.addEventLinstener(HomeUi.event_请求房间, () => {
    if (!isConnect()) {
      Tools.showPrompt("未连接到服务器!", 2000, Tools.PromptIcon.erro);
      return;
    }
    HomeUi.showRoomPanel();
    $(".rooms-response .loaderbox").show(); //显示加载标签
    $(".rooms-response .nullroom").hide();
    stopUpdateRank();
    startUpdateRooms();
  });
  HomeUi.addEventLinstener(HomeUi.event_退出房间界面, () => {
    stopUpdateRooms();
    startUpdateRank();
  });
  HomeUi.addEventLinstener(HomeUi.event_进入房间界面, (rid: string) => {
    var r = Enumerable.from(rooms).first((m) => m.RoomID == rid);
    var pwd = "";
    if (parseInt(myPlayer.Mark) < r.BtScore) {
      Tools.showMsbox("欢乐币不够了诶", "提示");
      return;
    }
    if (r.IsLock) {
      pwd = window.prompt("请输入房间密码:");
    }
    var obj = {
      roomid: rid,
      pwd: pwd,
    };
    sendData(JSON.stringify(obj), HallOrderType.请求进入房间);
  });
  HomeUi.addEventLinstener(HomeUi.event_房间查询, (value: string) => {
    if (value.length == 0) {
      HomeUi.hideQuerydRoom();
      return;
    }
    var result = Enumerable.from(rooms)
      .where((r) => {
        return r.MasterName.indexOf(value) >= 0 || r.RoomID.indexOf(value) >= 0;
      })
      .toArray();
    HomeUi.setQueryRoom(result);
  });
  HomeUi.addEventLinstener(HomeUi.event_发送广播, (mes: string) => {
    Tools.showMsbox("需要支付8888欢乐币,确认继续发送吗?", "支付提示", Tools.MsButtons.yesAndNo, (ok: boolean) => {
      if (ok) {
        var rem = parseInt(myPlayer.Mark);
        if (rem < 8888) {
          Tools.showPrompt("欢乐币不足,发送失败!", Tools.PromptIcon.erro);
        } else {
          myPlayer.Mark = (parseInt(myPlayer.Mark) - 8888).toString();
          HomeUi.setHallData(myPlayer);
          sendData("", HallOrderType.发送广播消息, mes);
          Tools.showPrompt("发送成功!");
        }
        $("#putradio").val("");
        $(".radio #rembyte").text("0");
        return;
      } else {
        Tools.showPrompt("已取消!");
      }
    });
  });
}

/**Callback->定时发送通知公告 */
function sendSysBar() {
  HomeUi.addBarrage("[系统消息]", "游戏上线初期难免会有若干BUG,可联系QQ:1083092844反馈");
}

/**Callback->成功连接websocket时触发 */
function playerConnect(e: Event) {
  var pid = Tools.getCookie("pid");
  console.log("发起的pid" + pid);
  if (conTimeOut) clearTimeout(conTimeOut);
  HomeUi.hideLoad();
  sendData("", HallOrderType.请求大厅数据, pid);
  startUpdateRank();
}

/**Callback->收到数据触发*/
function onData(e: MessageEvent<string>) {
  let bas = <NetInfoBase>JSON.parse(e.data);
  let jsonData = bas.JsonData;
  switch (bas.OrderType) {
    case HallOrderType.返回大厅数据: {
      var obj = JSON.parse(jsonData);
      let pinfo: NetPlayer = obj.Player;
      let flogin: boolean = obj.IsFirstLogin;
      myPlayer = pinfo;
      HomeUi.setHallData(pinfo);
      Tools.setCookie("pid", pinfo.PlayerID);
      if (flogin) HomeUi.showChangeInfoPanel();
      Tools.showPrompt("大厅连接成功!");
      break;
    }
    case HallOrderType.房间创建完毕: {
      let obj = JSON.parse(jsonData);
      Tools.setCookie("roomid", obj.roomid);
      Tools.skipRoom(obj.pid, obj.roomid, obj.roompwd);
      break;
    }
    case HallOrderType.推送房间列表: {
      var newroms = <NetRoom[]>JSON.parse(bas.JsonData);
      //删除不包含在新列表中的房间
      Enumerable.from(rooms)
        .where((r) => !Enumerable.from(newroms).any((r2) => r2.RoomID == r.RoomID))
        .toArray()
        .forEach((r) => {
          HomeUi.removeRoom(r.RoomID);
        });
      $(".rooms-response .loaderbox").hide();
      if (newroms.length > 0) {
        $(".rooms-response .nullroom").hide();
        newroms.forEach((r) => {
          HomeUi.addRoom(r);
        });
      } else {
        $(".rooms-response .nullroom").show();
      }
      rooms = newroms;
      break;
    }
    case HallOrderType.推送排名信息: {
      var rks: NetPlayer[] = JSON.parse(jsonData);
      setRankPanel(rks);
      break;
    }
    case HallOrderType.允许进入房间: {
      var obj = JSON.parse(bas.JsonData);
      Tools.setCookie("roomid", obj.roomid);
      Tools.skipRoom(myPlayer.PlayerID, obj.roomid, obj.pwd);
      break;
    }
    case HallOrderType.拒绝进入房间: {
      Tools.showMsbox(bas.Tag, "拒绝进入");
      break;
    }
    case HallOrderType.发送广播消息: {
      var obj = JSON.parse(jsonData);
      var sys: boolean = obj.sys;
      var name: string = obj.name;
      var mes: string = obj.mes;
      HomeUi.addBarrage(name, mes, sys);
      break;
    }
  }
}

//Callback->ws断开时触发
function onClose(e: CloseEvent) {
  showConnectFail();
}

//CallBack->到达排名更新周期时触发
function onGetRank() {
  sendData("", HallOrderType.请求排名信息);
}

//CallBack->到达房间更新周期时触发
function onGetRooms() {
  sendData("", HallOrderType.请求房间列表);
}

/**返回是否已连接 */
function isConnect() {
  if (!ws) return false;
  return ws.readyState == ws.OPEN;
}

/**启动排名更新 */
function startUpdateRank() {
  sendData("", HallOrderType.请求排名信息);
  rktimer = setInterval(onGetRank, rankCycle);
}

/**停止排名更新 */
function stopUpdateRank() {
  if (rktimer) {
    clearTimeout(rktimer);
  }
}

/**启动房间更新 */
function startUpdateRooms() {
  sendData("", HallOrderType.请求房间列表);
  rmtimer = setInterval(onGetRooms, roomsCycle);
}

/**停止房间更新 */
function stopUpdateRooms() {
  if (rmtimer) {
    clearInterval(rmtimer);
  }
}

/**发送数据*/
function sendData(json: string, type: HallOrderType, tag: string = "") {
  if (ws.readyState !== WebSocket.OPEN) return;
  let base = new NetInfoBase(type, json, tag);
  let str = JSON.stringify(base);
  ws.send(str);
}

/**设置排名信息 */
function setRankPanel(rks: NetPlayer[]) {
  $(".rank .they").html("");
  $("#myrank").text("未上榜");
  for (let i = 0; i < rks.length; i++) {
    let p = rks[i];
    let item = ` <div class="head flex-center">
    <img src="../static/img/HeadImgs/an${p.HeadID}.png" />
   </div>
   <div class="info flex-center">
    <div class="name"><span>${p.Name}</span></div>
    <div class="moy flex-center"><span>${Tools.markUnitConver(parseInt(p.Mark))}</span></div>
  </div>
  <div class="no">No.${i + 1}</div>`;
    let div = document.createElement("div");
    div.className = "rkitem";
    div.innerHTML = item;
    $(".rank .they").append(div);
    //如果发现我的排名则更新
    if (p.IP == myPlayer.IP) {
      $("#myrank").text(i + 1);
    }
  }
}
